<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
  </head>
  <body>
    <script>
      var vnode = {
        tag: "ul",
        props: {
          class: "list",
        },
        text: "",
        children: [
          {
            tag: "li",
            props: {
              class: "item",
            },
            text: "",
            children: [
              {
                tag: undefined,
                props: {},
                text: "牛客网",
                children: [],
              },
            ],
          },
          {
            tag: "li",
            props: {},
            text: "",
            children: [
              {
                tag: undefined,
                props: {},
                text: "nowcoder",
                children: [],
              },
            ],
          },
        ],
      };
      /**
       * 一眼递归，前面写过类似方式的递归，这里就讲一下操作过程中的注意事项
       * 首先是各种判空判undefined的情况，我这里写了部分必要的，
       * 其实按理可以使用可选链.?进一步剔除可能导致报错的情况，但大家都知道牛客判题器不支持，改来改去麻烦，感兴趣的小友可以自行加上
       * 这里大多数函数之前的题都用过，想必小友也很熟了，
       * 当然也有一个新面孔setAttribute，为dom设置属性的方法，用法也很简单，
       * 这里需要提醒一下appendChild会默认将新dom加在父dom第一级，如果直接传最开始的父元素是无法符合要求的，所以我们传递的是子代的引用
       * 具体的细节需要小友耐心理清思路，以提升对递归思想的理解
       */
      const _createElm = (vnode) => {
        // 补全代码

        //获取当前节点
        const getDomTemp = (vnode) => {
          let getDomTemp = document.createElement(vnode.tag);
          setAttributeArray(getDomTemp, vnode.props);
          getDomTemp.innerHTML = vnode.text;
          return getDomTemp;
        };

        // 递归获取节点
        const recursionGetDom = (vnode, getDom) => {
          if (vnode.children.length) {
            let tempDom = getDomTemp(vnode);
            getDom.appendChild(tempDom);
            vnode.children.forEach((item) => {
              recursionGetDom(item, tempDom);
            });
          } else {
            getDom.appendChild(getDomTemp(vnode));
            return;
          }
        };

        // 设置属性
        const setAttributeArray = (getDom, props) => {
          for (let key in props) {
            getDom.setAttribute(key, props[key]);
          }
        };

        //开始执行
        if (!Object.keys(vnode).length) return null;
        let returnDom = getDomTemp(vnode);
        if (!vnode.children.length) return returnDom;
        vnode.children.forEach((item) => {
          recursionGetDom(item, returnDom);
        });
        return returnDom;
      };
      // 测试代码
      function aaa() {var dom = _createElm(vnode); var li = dom.querySelector('li');var result = li.innerText == '牛客网' ; return result; }
      console.log(aaa());
      </script>
  </body>
</html>
